package com.joysuch.wwyt.common.service.impl;

import com.joysuch.wwyt.baidu.controller.DzPrtqFaceController;
import com.joysuch.wwyt.baidu.enums.BaiduCodeEnum;
import com.joysuch.wwyt.baidu.req.BaiduFace;
import com.joysuch.wwyt.baidu.req.BaiduSample;
import com.joysuch.wwyt.baidu.util.DzPrtqUtils;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.common.service.CommonFaceService;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BaseImageRepositoryService;
import com.joysuch.wwyt.core.service.BaseUserFaceApiLogService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import picocli.CommandLine;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

/**
 * @author xsx
 * @version 1.0
 * @date 2023/3/16 9:52
 */
@Service
@Transactional
public class CommonFaceServiceImpl implements CommonFaceService {

    private static final Logger logger = LoggerFactory.getLogger(DzPrtqFaceController.class);

    @Autowired
    private BaseConfigService baseConfigService;

    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BaseImageRepositoryService baseImageRepositoryService;

    @Autowired
    private BaseUserFaceApiLogService baseUserFaceApiLogService;


    @Override
    public Object compare(MultipartFile file, Long userId) throws IOException {
        if (userId == null) {
            userId = Context.getCurrentUserId();
        }
        BaseUser user = baseUserDao.getOne(userId);
        if (user.getIdCardImgId() == null) {
            return ResultBean.fail(4001, "头像不存在, 请联系管理员添加头像");
        }
        String path = baseImageRepositoryService.findAbsolutePathById(user.getIdCardImgId());
        String base = DzPrtqUtils.readFileToBase64(new FileInputStream(path));
        String upload = DzPrtqUtils.readFileToBase64(file.getInputStream());
        try {
            JSONObject json = new BaiduFace().compare(BaiduSample.client, base, upload);
            logger.debug("请求人脸返回: {}", json.toString(2));
            baseUserFaceApiLogService.saveLog(userId,"compare","https://aip.baidubce.com/rest/2.0/face/v3/match","",json.toString());
            if (isSuccess(json)) {
                double threshold = 80;
                JSONObject jo = json.getJSONObject("result");
                Double score = jo.getDouble("score");
                BaseConfig config = baseConfigService.findConfig(Constant.APP_FACE_RECOGNITION_ACCURACY);
                if (config != null && StringUtils.isNotBlank(config.getValue())) {
                    threshold = Double.valueOf(config.getValue());
                }
                logger.info("用户#{}人脸比对分数={}, 门限值为{}", userId, score, threshold);
                if (score >= threshold) {
                    return ResultBean.success("成功");
                }
            }
        } catch (JSONException e) {
            return ResultBean.fail(4003, "人脸识别失败，请重新再试");
        } catch (NumberFormatException e) {
            return ResultBean.fail(4003, "人脸识别失败，请重新再试");
        }
        return ResultBean.fail(4003, "人脸识别失败，请重新再试");
    }

    @Override
    public ResultBean search(MultipartFile file) {
        Map<String,String> map=new HashMap<>();
        try {
            Long userId = Context.getCurrentUserId();
            BaseConfig buildIdConfig = baseConfigService.findFirstConfig(BaseConfigCodes.LOCATE_CURRENT_BUILD_ID);
            String groupId="";
            if (buildIdConfig!=null ) {
                groupId =buildIdConfig.getValue();
            }
            String imageBase64 = DzPrtqUtils.readFileToBase64(file.getInputStream());
            JSONObject jsonObject = new BaiduFace().search(BaiduSample.client, imageBase64, "BASE64", groupId, null);
            String errorCode = jsonObject.get("error_code").toString();
            baseUserFaceApiLogService.saveLog(userId,"search","https://aip.baidubce.com/rest/2.0/face/v3/search","",jsonObject.toString());
            if (errorCode.equals("0")) {
                JSONObject result = jsonObject.getJSONObject("result");
                String faceToken = result.getString("face_token");
                JSONArray array = result.getJSONArray("user_list");
                if (array!=null&&array.getJSONObject(0)!=null) {
                    JSONArray jsonArray = jsonArraySort(result.getJSONArray("user_list"));
                    Double score = jsonArray.getJSONObject(0).getDouble("score");
                    Double  threshold=80d;
                    BaseConfig config = baseConfigService.findConfig(Constant.APP_FACE_RECOGNITION_ACCURACY);
                    if (config != null && StringUtils.isNotBlank(config.getValue())) {
                        threshold = Double.valueOf(config.getValue());
                    }
                    if (score<threshold){
                        return ResultBean.fail(4003, "人脸识别错误，请确认员工头像是否上传或清晰后重新识别");
                    }
                    String user_id = jsonArray.getJSONObject(0).getString("user_id");
                    if (StringUtils.isBlank(user_id)) {
                        return ResultBean.fail(4003, "人脸识别错误，请确认员工头像是否上传或清晰后重新识别");
                    }
                    BaseUser baseUser = baseUserDao.getUserByUserId(Long.parseLong(user_id));
//                    if (!byId.isPresent()) {
//                        return ResultBean.fail(4003, "人脸搜索失败");
//                    }
//                    BaseUser baseUser =byId.orElse(null);
                    if (baseUser!=null) {
//                        int i = baseUser.getAutograph().indexOf("=");
//                        Long id = Long.parseLong(baseUser.getAutograph().substring(i+1));
//                        String path = baseImageRepositoryService.findById(id).getOriginPath();
                        map.put("path",baseUser.getFlowSignature());
                        map.put("autograph",baseUser.getAutograph());
                        map.put("realName",baseUser.getRealName());
                        map.put("code",baseUser.getCode());
                    }
                    else {
                        return ResultBean.fail(4003, "人脸识别错误，请确认员工头像是否上传或清晰后重新识别");
                    }
                }else {
                    return ResultBean.fail(4003, "人脸搜索失败,未找到人员faceToken："+faceToken);
                }
            } else {
                BaiduCodeEnum baiduCodeEnum = BaiduCodeEnum.find(errorCode);
                String msg = baiduCodeEnum == null ? "人脸识别失败,错误代码:" + errorCode : baiduCodeEnum.getErrMsg();
                return ResultBean.fail(4003, msg);
            }
            return ResultBean.success(map);
        }
        catch (IOException e) {
            return ResultBean.fail(4003, "人脸搜索失败");
        }
    }


    private boolean isSuccess(JSONObject json) {
        return json.getInt("error_code") == 0;
    }



    public static JSONArray  jsonArraySort(JSONArray jsonArr) {
        // json字符串转为JSONArray
//        JSONArray jsonArr = JSON.parseArray(jsonArrStr);
        //存放排序结果json数组
        JSONArray sortedJsonArray = new JSONArray();
        // 用于排序的list
        List<JSONObject> list = new ArrayList<JSONObject>();
        //遍历待排序的json数组，并将数据放入list
        for (int i = 0; i < jsonArr.length(); i++) {
            list.add(jsonArr.getJSONObject(i));
        }

        Collections.sort(list, new Comparator<JSONObject>() {
            //排序字段
            private static final String KEY_NAME2 = "score";

            @Override
            public int compare(JSONObject b, JSONObject a) {
                String valA1 = new String();
                String valA2 = new String();
                String valB1 = new String();
                String valB2 = new String();
                try {
                    valB1 = a.getString(KEY_NAME2);
                    valB2 = b.getString(KEY_NAME2);
                } catch (JSONException e) {
                    System.out.println(e);
                }
                // 设置排序规则
                int i = valA1.compareTo(valA2);
                if (i == 0) {
                    int j = valB1.compareTo(valB2);
                    return j;
                }
                return i;
            }
        });
        //将排序后结果放入结果jsonArray
        for (int i = 0; i < jsonArr.length(); i++) {
            sortedJsonArray.put(list.get(i));
        }
        return sortedJsonArray;
    }
}
